/*============================================================================
* Name:         SNMP
* Purpose:
* Author:       xu wei
* Date:         2014/09/22
* Notes:
*
* Revision 1.0
* no message
*
*=============================================================================
*/

#ifndef __SNMP_H__
#define __SNMP_H__

#include "types.h"
#include "mib.h"
#include "lwip/udp.h"

#define SNMPMAXHEADLEN      32

#define MAX_SNMP_LENGTH     208
#define SNMP_AGENT_PORT     161
#define TRAP_TARGET_PORT    162

#define SNMP_CONCURRENT_REQUESTS        1

#define SNMP_STATE_FREE             0
#define SNMP_STATE_WAIT             1
#define SNMP_STATE_CONNECTED        2
#define SNMP_STATE_RECEIVE          3

#define EFFECT_TRAPIP       1
#define NOEFFECT_TRAPIP     2

#define OK           1
#define SYSERR      -1
//#define EOF         -2
#define TIMEOUT     -3
#define INTRMSG     -4

#define ASN1_SEQ        0x30
#define ASN1_INT        0x02
#define ASN1_OCTSTR     0x04
#define ASN1_NULL       0x05
#define ASN1_OBJID      0x06
#define ASN1_IPADDR     0x40
#define ASN1_COUNTER    0x41
#define ASN1_GAUGE      0x42
#define ASN1_TIMETICKS  0x43

#define PDU_GET         0xA0
#define PDU_GETN        0xA1
#define PDU_RESP        0xA2
#define PDU_SET         0xA3
#define PDU_TRAP        0xA4

#define TRAP_CS         0x00
#define TRAP_WS         0x02
#define TRAP_AE         0x01

#define CHAR_BITS       8
#define CHAR_HIBIT      0x80
#define BYTE2_HIBIT     0x8000
#define BYTE3_HIBIT     0x800000
#define BYTE4_HIBIT     0x80000000

#define LEAF            1
#define NLEAF           0

#define T_TABLE             01
#define T_AGGREGATE         0xa

#define SNMP_OK             0
#define SERR_TOO_BIG        1
#define SERR_NO_SUCH        2
#define SERR_BAD_VALUE      3
#define SERR_READ_ONLY      4
#define SERR_GEN_ERROR      5

#define SVERS_LEN       1
#define SVERSION        0

#define SOP_GET         1
#define SOP_GETN        2
#define SOP_GETF        3
#define SOP_SET         4

#define MIB_PREF_SZ     9

#define SNUMF_AP        		8
#define SNUMF_CA        		3
#define SNUMF_AL        		2
#define SNUMF_CT        		4
#define SNUMF_OA        		4
#define SNUMF_OPS       		4
#define SNUMF_DOR_RX_INPUT		5
#define SNUMF_DOR_RX_OUTPUT		9
#define SNUMF_DOR_DC_POWER		4
#define SNUMF_DOR_STATUS		3


#define T_OA_POWERSUPPLY_TABLE      0x00
#define T_OA_PUMP_TABLE             0x01
#define T_COMTRAPTABLE              0x02
#define T_ALARMLOGTABLE             0x03
#define T_CURALARMTABLE             0x04
#define T_APROPTABLE                0x05
#define T_DOR_RX_INPUT_TABLE		0x06
#define	T_DOR_RX_OUTPUT_TABLE		0x07
#define	T_DOR_DC_POWER_TABLE		0x08
#define	T_DOR_STATUS_TABLE			0x09



#define S_NUMTABS           6

#define S_HTABSIZ           61
#define S_HTRADIX           8

#define TABLE_OIDLEN        3

#define A1_SIGNED(x)    ((x) == ASN1_INT)

#define oidequ(x,y)     ((x)->len == (y)->len && !memcmp((x)->id, (y)->id, (y)->len * 2))

#define IP_ALEN         4

typedef char    bool;
typedef U32_T   IPaddr;

struct  getp
{
    struct snbentry *bindl;
    struct mib_info *mip;
};

struct  mif
{
    struct snbentry *bindl;
    struct mib_info  *mip;
    S16_T  op;
};

struct snmp_msg_pstat
{
    struct udp_pcb *pcb;
    struct ip_addr sip;
    u16_t sp;
    u8_t state;
};

struct snmp_msg_trap
{
    struct udp_pcb *pcb;
    struct ip_addr dip;
};

struct snval
{
    U8_T    sv_type;
    union
    {
        S32_T   sv_int;
        struct
        {
            S8_T *sv_str;
            S16_T sv_len;
        } sv_str;
        struct  oid sv_oid;
        IPaddr  sv_ipaddr;
    } sv_val;
};

#define SVTYPE(bl)      ((bl)->sb_val.sv_type)
#define SVINT(bl)       ((bl)->sb_val.sv_val.sv_int)
#define SVSTR(bl)       ((bl)->sb_val.sv_val.sv_str.sv_str)
#define SVSTRLEN(bl)    ((bl)->sb_val.sv_val.sv_str.sv_len)
#define SVOID(bl)       ((bl)->sb_val.sv_val.sv_oid.id)
#define SVOIDLEN(bl)    ((bl)->sb_val.sv_val.sv_oid.len)
#define SVIPADDR(bl)    ((bl)->sb_val.sv_val.sv_ipaddr)

struct snbentry
{
    struct  oid sb_oid;
    struct  snval sb_val;
    U8_T    *sb_a1str;
    S16_T   sb_a1slen;
    bool    sb_a1dynstr;
    struct  snbentry *sb_next;
    struct  snbentry *sb_prev;
};

struct req_desc
{
    U8_T    reqtype;
    U8_T    reqid[10];
    S16_T   reqidlen;
    U8_T    err_stat;
    U8_T    err_idx;
    S16_T   err_stat_pos;
    S16_T   err_idx_pos;
    S16_T   pdutype_pos;
    struct  snbentry *bindlf;
    struct  snbentry *bindle;
};

struct mib_info
{
    struct  oid mi_objid;
    U8_T    mi_vartype;
    bool    mi_writable;
    bool    mi_varleaf;
    S16_T(*mi_func)(struct mif *);
    S8_T    *mi_param;
    struct  mib_info *mi_next;
};

struct tab_info
{
    S16_T(*ti_get)(struct snbentry *);
    S16_T(*ti_getf)(struct getp *);
    S16_T(*ti_getn)(struct getp *);
    S16_T(*ti_set)(struct snbentry *);
    S16_T(*ti_match)(struct snbentry *, S16_T *, S16_T *);
    struct  mib_info *ti_mip;
};

struct snhnode
{
    struct mib_info *sh_mip;
    struct snhnode *sh_next;
};

extern volatile U8_T coldstartf;
extern volatile U8_T warmstartf;

extern U8_T     ipsetf, gwsetf, mksetf;
extern U8_T     alarmnum ;

extern struct oaDeviceGroup         oaDev;
extern struct dorDeviceGroup dorDev;

void    snmp_init(void);
S16_T   oidcmp(U16_T  *oid1, U16_T  *oid2, U16_T len);
S16_T   a1writeoid(U8_T *packp, struct oid *oidp);
S16_T   a1writeint(S32_T val, U8_T *buffp, S16_T a1type);
void    trap(void);
S16_T   MIBInit(void);


#endif /* _SNMP_H */
